package cn.yunhe.util;

import cn.yunhe.excep.OutOfStockException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogUtil {

    @Before("p()")
    public void before(JoinPoint jp) {
        Object[] args = jp.getArgs();
        String mname = jp.getSignature().getName();
        if ("buyPhone".equals(mname))
            System.out.println("前置通知:日志:" + DateFormat.simDate() + "购入" + args[0] + "部PHONE");
        if ("salePhone".equals(mname))
            System.out.println("前置通知:日志:" + DateFormat.simDate() + "出售" + args[0] + "部PHONE");
    }

    @AfterReturning("p()")
    public void afterReturning(JoinPoint jp) {
        String mname = jp.getSignature().getName();
        if ("buyPhone".equals(mname))
            System.out.println("后置通知:日志:" + DateFormat.simDate() + "购入手机执行完毕");
        if ("salePhone".equals(mname))
            System.out.println("后置通知:日志:" + DateFormat.simDate() + "出售手机执行完毕");
    }

    @AfterThrowing(pointcut = "p()", throwing = "e")
    public void afterThrowing(JoinPoint jp, OutOfStockException e) {
        String methodName = jp.getSignature().getName();
        System.out.println("异常通知:" + DateFormat.simDate() + methodName + "方法被执行,但发生库存异常" + e.getMessage());
    }

    @After("p()")
    public void after(JoinPoint jp) {
        String mname = jp.getSignature().getName();
        if ("buyPhone".equals(mname))
            System.out.println("最终通知:日志:" + DateFormat.simDate() + "进货方法执行完毕,发生异常也执行的最终通知");
        if ("salePhone".equals(mname))
            System.out.println("最终通知:日志:" + DateFormat.simDate() + "出售方法执行完毕,发生异常也执行的最终通知");
    }

    @Around("p()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        String methodName = pjp.getSignature().getName();
        long begin = System.currentTimeMillis();
        System.out.println("环绕通知:" + DateFormat.simDate() + "," + methodName + "方法开始执行");
        try {
            return pjp.proceed();
        } finally {
            long end = System.currentTimeMillis();
            System.out.println("环绕通知:" + DateFormat.simDate() + "," + methodName + "方法执行完毕,用时:" + (end - begin) + "毫秒");

        }
    }

    @Pointcut("execution(void *Phone(int))")
    public void p() {
    }
}
